home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / MKLEV.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  30KB  |  1,271 lines

  1. /*    SCCS Id: @(#)mklev.c    3.0    89/12/06
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
  8. /* croom->lx etc are schar (width <= int), so % arith ensures that */
  9. /* conversion of result to int is reasonable */
  10.  
  11. #ifdef SINKS
  12. static void FDECL(mksink,(struct mkroom *));
  13. #endif
  14. #ifdef ALTARS
  15. static void FDECL(mkaltar,(struct mkroom *));
  16. #endif
  17. static boolean FDECL(occupied,(XCHAR_P,XCHAR_P));
  18. static void NDECL(makevtele);
  19. static void NDECL(init_levels);
  20. static void NDECL(makelevel);
  21. static boolean FDECL(bydoor,(XCHAR_P,XCHAR_P));
  22. static boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*));
  23. static void FDECL(makeniche,(int));
  24. static void NDECL(make_niches);
  25. static void NDECL(makebigroom);
  26. static void FDECL(addrsx,(int,int,int,int,BOOLEAN_P));
  27. static void FDECL(addrs,(int,int,int,int));
  28. STATIC_PTR int FDECL(comp,(genericptr_t,genericptr_t));
  29. static void FDECL(dosdoor,(int,int,struct mkroom *,int));
  30. static void NDECL(makecorridors);
  31. static void FDECL(join,(int,int));
  32. static int NDECL(makerooms);
  33. static int FDECL(maker,(SCHAR_P,SCHAR_P,SCHAR_P,SCHAR_P,BOOLEAN_P));
  34. static void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
  35.  
  36. int
  37. somex(croom)
  38. register struct mkroom *croom;
  39. {
  40.     return rn2(croom->hx-croom->lx+1) + croom->lx;
  41. }
  42.  
  43. int
  44. somey(croom)
  45. register struct mkroom *croom;
  46. {
  47.     return rn2(croom->hy-croom->ly+1) + croom->ly;
  48. }
  49.  
  50. #define    XLIM    4    /* define minimum required space around a room */
  51. #define    YLIM    3
  52. boolean secret;        /* TRUE while making a vault: increase [XY]LIM */
  53. struct rm zerorm;
  54. schar nxcor;
  55. boolean goldseen;
  56.  
  57. /* Definitions used by makerooms() and addrs() */
  58. #define    MAXRS    50    /* max lth of temp rectangle table - arbitrary */
  59. struct rectangle {
  60.     xchar rlx,rly,rhx,rhy;
  61. } rs[MAXRS+1];
  62. int rscnt,rsmax;    /* 0..rscnt-1: currently under consideration */
  63.             /* rscnt..rsmax: discarded */
  64.  
  65. static void
  66. addrsx(lx,ly,hx,hy,discarded)
  67. register int lx,ly,hx,hy;
  68. boolean discarded;        /* piece of a discarded area */
  69. {
  70.     register struct rectangle *rsp;
  71.  
  72.     /* check inclusions */
  73.     for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
  74.         if(lx >= rsp->rlx && hx <= rsp->rhx &&
  75.            ly >= rsp->rly && hy <= rsp->rhy)
  76.             return;
  77.     }
  78.  
  79.     /* make a new entry */
  80.     if(rsmax >= MAXRS) {
  81. #ifdef WIZARD
  82.         if(wizard) pline("MAXRS may be too small.");
  83. #endif
  84.         return;
  85.     }
  86.     rsmax++;
  87.     if(!discarded) {
  88.         *rsp = rs[rscnt];
  89.         rsp = &rs[rscnt];
  90.         rscnt++;
  91.     }
  92.     rsp->rlx = lx;
  93.     rsp->rly = ly;
  94.     rsp->rhx = hx;
  95.     rsp->rhy = hy;
  96. }
  97.  
  98. static void
  99. addrs(lowx,lowy,hix,hiy)
  100. register int lowx,lowy,hix,hiy;
  101. {
  102.     register struct rectangle *rsp;
  103.     register int lx,ly,hx,hy,xlim,ylim;
  104.     boolean discarded;
  105.  
  106.     xlim = XLIM + secret;
  107.     ylim = YLIM + secret;
  108.  
  109.     /* walk down since rscnt and rsmax change */
  110.     for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
  111.  
  112.         if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
  113.            (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
  114.             continue;
  115.         if((discarded = (rsp >= &rs[rscnt]))) {
  116.             *rsp = rs[--rsmax];
  117.         } else {
  118.             rsmax--;
  119.             rscnt--;
  120.             *rsp = rs[rscnt];
  121.             if(rscnt != rsmax)
  122.                 rs[rscnt] = rs[rsmax];
  123.         }
  124.         if(lowy - ly > 2*ylim + 4)
  125.             addrsx(lx,ly,hx,lowy-2,discarded);
  126.         if(lowx - lx > 2*xlim + 4)
  127.             addrsx(lx,ly,lowx-2,hy,discarded);
  128.         if(hy - hiy > 2*ylim + 4)
  129.             addrsx(lx,hiy+2,hx,hy,discarded);
  130.         if(hx - hix > 2*xlim + 4)
  131.             addrsx(hix+2,ly,hx,hy,discarded);
  132.     }
  133. }
  134.  
  135. /* Args must be genericptr_t so that qsort will always be happy. */
  136.  
  137. STATIC_PTR int
  138. comp(vx,vy)
  139. genericptr_t vx;
  140. genericptr_t vy;
  141. {
  142. #ifdef LINT
  143. /* lint complains about possible pointer alignment problems, but we know
  144.    that vx and vy are always properly aligned. Hence, the following
  145.    bogus definition:
  146. */
  147.     return (vx == vy) ? 0 : -1;
  148. #else
  149.     register struct mkroom *x, *y;
  150.  
  151.     x = (struct mkroom *)vx;
  152.     y = (struct mkroom *)vy;
  153.     if(x->lx < y->lx) return(-1);
  154.     return(x->lx > y->lx);
  155. #endif /* LINT */
  156. }
  157.  
  158. static void
  159. finddpos(cc, xl,yl,xh,yh)
  160. coord    *cc;
  161. xchar    xl,yl,xh,yh;
  162. {
  163.     register xchar x, y;
  164.  
  165.     x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
  166.     y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
  167.     if(okdoor(x, y))
  168.         goto gotit;
  169.  
  170.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  171.         if(okdoor(x, y))
  172.             goto gotit;
  173.  
  174.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  175.         if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
  176.             goto gotit;
  177.     /* cannot find something reasonable -- strange */
  178.     x = xl;
  179.     y = yh;
  180. gotit:
  181.     cc->x = x;
  182.     cc->y = y;
  183.     return;
  184. }
  185.  
  186. /* Only called from makerooms() and makebigroom() */
  187. static int
  188. maker(lowx,ddx,lowy,ddy,lit)
  189. schar lowx,ddx,lowy,ddy;
  190. boolean lit;
  191. {
  192.     register struct mkroom *croom;
  193.     register int x, y, hix = lowx+ddx, hiy = lowy+ddy;
  194.     register int xlim = XLIM + secret, ylim = YLIM + secret;
  195.  
  196.     if(nroom >= MAXNROFROOMS) return(0);
  197.     if(lowx < XLIM) lowx = XLIM;
  198.     if(lowy < YLIM) lowy = YLIM;
  199.     if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
  200.     if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
  201. chk:
  202.     if(hix <= lowx || hiy <= lowy) return(0);
  203.  
  204.     /* check area around room (and make room smaller if necessary) */
  205.     for(x = lowx - xlim; x <= hix + xlim; x++) {
  206.         for(y = lowy - ylim; y <= hiy + ylim; y++) {
  207.             if(isok(x,y) && levl[x][y].typ) {
  208. #ifdef WIZARD
  209.                 if(wizard && !secret)
  210.                 pline("Strange area [%d,%d] in maker().",x,y);
  211. #endif
  212.                 if(!rn2(3)) return(0);
  213.                 if(x < lowx)
  214.                     lowx = x+xlim+1;
  215.                 else
  216.                     hix = x-xlim-1;
  217.                 if(y < lowy)
  218.                     lowy = y+ylim+1;
  219.                 else
  220.                     hiy = y-ylim-1;
  221.                 goto chk;
  222.             }
  223.         }
  224.     }
  225.  
  226.     croom = &rooms[nroom];
  227.  
  228.     /* on low levels the room is lit (usually) */
  229.     /* secret vaults are always lit */
  230.     /* some other rooms may require lighting */
  231.     if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) {
  232.         for(x = lowx-1; x <= hix+1; x++)
  233.             for(y = lowy-1; y <= hiy+1; y++)
  234.                 levl[x][y].lit = 1;
  235.         croom->rlit = 1;
  236.     } else
  237.         croom->rlit = 0;
  238.     croom->lx = lowx;
  239.     croom->hx = hix;
  240.     croom->ly = lowy;
  241.     croom->hy = hiy;
  242.     croom->rtype = OROOM;
  243.     croom->doorct = 0;
  244.     /* if we're not making a vault, doorindex will still be 0
  245.      * if we are, we'll have problems adding niches to the previous room
  246.      * unless fdoor is at least doorindex
  247.      */
  248.     croom->fdoor = doorindex;
  249.  
  250.     for(x = lowx-1; x <= hix+1; x++)
  251.         for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  252.         levl[x][y].typ = HWALL;
  253.         levl[x][y].scrsym = HWALL_SYM;
  254.         }
  255.     for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  256.         for(y = lowy; y <= hiy; y++) {
  257.         levl[x][y].typ = VWALL;
  258.         levl[x][y].scrsym = VWALL_SYM;
  259.         }
  260.     for(x = lowx; x <= hix; x++)
  261.         for(y = lowy; y <= hiy; y++) {
  262.         levl[x][y].typ = ROOM;
  263.         levl[x][y].scrsym = ROOM_SYM;
  264.         }
  265.     levl[lowx-1][lowy-1].typ = TLCORNER;
  266.     levl[hix+1][lowy-1].typ = TRCORNER;
  267.     levl[lowx-1][hiy+1].typ = BLCORNER;
  268.     levl[hix+1][hiy+1].typ = BRCORNER;
  269.     levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
  270.     levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
  271.     levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
  272.     levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
  273.  
  274.     smeq[nroom] = nroom;
  275.     croom++;
  276.     croom->hx = -1;
  277.     nroom++;
  278.     return(1);
  279. }
  280.  
  281. static int
  282. makerooms() {
  283. register struct rectangle *rsp;
  284. register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
  285. int tryct = 0, xlim, ylim;
  286.  
  287.     /* init */
  288.     xlim = XLIM + secret;
  289.     ylim = YLIM + secret;
  290.     if(nroom == 0) {
  291.         rsp = rs;
  292.         rsp->rlx = rsp->rly = 0;
  293.         rsp->rhx = COLNO-1;
  294.         rsp->rhy = ROWNO-1;
  295.         rsmax = 1;
  296.     }
  297.     rscnt = rsmax;
  298.  
  299.     /* make rooms until satisfied */
  300.     while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
  301.         if(!secret && nroom > (MAXNROFROOMS/4) &&
  302.            !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
  303.             return 0;
  304.  
  305.         /* pick a rectangle */
  306.         rsp = &rs[rn2(rscnt)];
  307.         hx = rsp->rhx;
  308.         hy = rsp->rhy;
  309.         lx = rsp->rlx;
  310.         ly = rsp->rly;
  311.  
  312.         /* find size of room */
  313.         if(secret)
  314.             dx = dy = 1;
  315.         else {
  316.             dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
  317.             dy = 2 + rn2(4);
  318.             if(dx*dy > 50)
  319.                 dy = 50/dx;
  320.         }
  321.  
  322.         /* look whether our room will fit */
  323.         if(hx-lx < dx + (dx>>1) + 2*xlim ||
  324.            hy-ly < dy + dy/3 + 2*ylim) {
  325.                     /* no, too small */
  326.                     /* maybe we throw this area out */
  327.             if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
  328.                 rscnt--;
  329.                 rs[rsmax] = *rsp;
  330.                 *rsp = rs[rscnt];
  331.                 rs[rscnt] = rs[rsmax];
  332.                 tryct = 0;
  333.             } else
  334.                 tryct++;
  335.             continue;
  336.         }
  337.  
  338.         lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
  339.         lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
  340.         hix = lowx + dx;
  341.         hiy = lowy + dy;
  342.  
  343.         if(maker(lowx, dx, lowy, dy, FALSE)) {
  344.             if(secret) return(1);
  345.             addrs(lowx-1, lowy-1, hix+1, hiy+1);
  346.             tryct = 0;
  347.         } else
  348.             if(tryct++ > 100)
  349.                 break;
  350.     }
  351.     return(0);    /* failed to make vault - very strange */
  352. }
  353.  
  354. static void
  355. join(a,b)
  356. register int a, b;
  357. {
  358.     coord cc,tt;
  359.     register int tx, ty, xx, yy;
  360.     register struct rm *crm;
  361.     register struct mkroom *croom, *troom;
  362.     register int dx, dy, dix, diy, cct;
  363.  
  364.     croom = &rooms[a];
  365.     troom = &rooms[b];
  366.  
  367.     /* find positions cc and tt for doors in croom and troom
  368.        and direction for a corridor between them */
  369.  
  370.     if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
  371.     if(troom->lx > croom->hx) {
  372.         dx = 1;
  373.         dy = 0;
  374.         xx = croom->hx+1;
  375.         tx = troom->lx-1;
  376.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  377.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  378.     } else if(troom->hy < croom->ly) {
  379.         dy = -1;
  380.         dx = 0;
  381.         yy = croom->ly-1;
  382.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  383.         ty = troom->hy+1;
  384.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  385.     } else if(troom->hx < croom->lx) {
  386.         dx = -1;
  387.         dy = 0;
  388.         xx = croom->lx-1;
  389.         tx = troom->hx+1;
  390.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  391.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  392.     } else {
  393.         dy = 1;
  394.         dx = 0;
  395.         yy = croom->hy+1;
  396.         ty = troom->ly-1;
  397.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  398.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  399.     }
  400.     xx = cc.x;
  401.     yy = cc.y;
  402.     tx = tt.x - dx;
  403.     ty = tt.y - dy;
  404.     if(nxcor && levl[xx+dx][yy+dy].typ)
  405.         return;
  406.     dodoor(xx,yy,croom);
  407.  
  408.     cct = 0;
  409.     while(xx != tx || yy != ty) {
  410.         xx += dx;
  411.         yy += dy;
  412.  
  413.         /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
  414.         if(cct++ > 500 || (nxcor && !rn2(35)))
  415.         return;
  416.  
  417.         if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
  418.         return;        /* impossible */
  419.  
  420.         crm = &levl[xx][yy];
  421.         if(!(crm->typ)) {
  422.         if(rn2(100)) {
  423.             crm->typ = CORR;
  424.             crm->scrsym = CORR_SYM;
  425.             if(nxcor && !rn2(50))
  426.                 (void) mksobj_at(BOULDER, xx, yy);
  427.         } else {
  428.             crm->typ = SCORR;
  429.             crm->scrsym = ' ';    /* _not_ STONE_SYM */
  430.         }
  431.         } else
  432.         if(crm->typ != CORR && crm->typ != SCORR) {
  433.         /* strange ... */
  434.         return;
  435.         }
  436.  
  437.         /* find next corridor position */
  438.         dix = abs(xx-tx);
  439.         diy = abs(yy-ty);
  440.  
  441.         /* do we have to change direction ? */
  442.         if(dy && dix > diy) {
  443.         register int ddx = (xx > tx) ? -1 : 1;
  444.  
  445.         crm = &levl[xx+ddx][yy];
  446.         if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  447.             dx = ddx;
  448.             dy = 0;
  449.             continue;
  450.         }
  451.         } else if(dx && diy > dix) {
  452.         register int ddy = (yy > ty) ? -1 : 1;
  453.  
  454.         crm = &levl[xx][yy+ddy];
  455.         if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  456.             dy = ddy;
  457.             dx = 0;
  458.             continue;
  459.         }
  460.         }
  461.  
  462.         /* continue straight on? */
  463.         crm = &levl[xx+dx][yy+dy];
  464.         if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  465.         continue;
  466.  
  467.         /* no, what must we do now?? */
  468.         if(dx) {
  469.         dx = 0;
  470.         dy = (ty < yy) ? -1 : 1;
  471.         crm = &levl[xx+dx][yy+dy];
  472.         if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  473.             continue;
  474.         dy = -dy;
  475.         continue;
  476.         } else {
  477.         dy = 0;
  478.         dx = (tx < xx) ? -1 : 1;
  479.         crm = &levl[xx+dx][yy+dy];
  480.         if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  481.             continue;
  482.         dx = -dx;
  483.         continue;
  484.         }
  485.     }
  486.  
  487.     /* we succeeded in digging the corridor */
  488.     dodoor(tt.x, tt.y, troom);
  489.  
  490.     if(smeq[a] < smeq[b])
  491.         smeq[b] = smeq[a];
  492.     else
  493.         smeq[a] = smeq[b];
  494. }
  495.  
  496. static void
  497. makecorridors() {
  498.     register int a, b;
  499.  
  500.     nxcor = 0;
  501.     for(a = 0; a < nroom-1; a++)
  502.         join(a, a+1);
  503.     for(a = 0; a < nroom-2; a++)
  504.         if(smeq[a] != smeq[a+2])
  505.         join(a, a+2);
  506.     for(a = 0; a < nroom; a++)
  507.         for(b = 0; b < nroom; b++)
  508.         if(smeq[a] != smeq[b])
  509.             join(a, b);
  510.     if(nroom > 2)
  511.         for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
  512.         a = rn2(nroom);
  513.         b = rn2(nroom-2);
  514.         if(b >= a) b += 2;
  515.         join(a, b);
  516.         }
  517. }
  518.  
  519. static void
  520. dosdoor(x,y,aroom,type)
  521. register int x, y;
  522. register struct mkroom *aroom;
  523. register int type;
  524. {
  525.     register struct mkroom *broom;
  526.     register int tmp;
  527.     boolean shdoor = in_shop(x, y);
  528.  
  529.     if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */
  530.         type = DOOR;
  531.     levl[x][y].typ = type;
  532.     if(type == DOOR) {
  533.         if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
  534.         if(!rn2(5))
  535.             levl[x][y].doormask = D_ISOPEN;
  536.         else if(!rn2(6))
  537.             levl[x][y].doormask = D_LOCKED;
  538.         else
  539.             levl[x][y].doormask = D_CLOSED;
  540.  
  541.         if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
  542.             levl[x][y].doormask |= D_TRAPPED;
  543.         } else
  544. #ifdef STUPID
  545.         if (shdoor)
  546.             levl[x][y].doormask = D_ISOPEN;
  547.         else
  548.             levl[x][y].doormask = D_NODOOR;
  549. #else
  550.         levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
  551. #endif
  552.         levl[x][y].scrsym = news0(x,y);
  553.     } else { /* SDOOR */
  554.         if(shdoor || !rn2(5))    levl[x][y].doormask = D_LOCKED;
  555.         else            levl[x][y].doormask = D_CLOSED;
  556.  
  557.         if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
  558.     }
  559.     aroom->doorct++;
  560.     broom = aroom+1;
  561.     if(broom->hx < 0) tmp = doorindex; else
  562.     for(tmp = doorindex; tmp > broom->fdoor; tmp--)
  563.         doors[tmp] = doors[tmp-1];
  564.     doorindex++;
  565.     doors[tmp].x = x;
  566.     doors[tmp].y = y;
  567.     for( ; broom->hx >= 0; broom++) broom->fdoor++;
  568. }
  569.  
  570. static boolean
  571. place_niche(aroom,dy,xx,yy)
  572. register struct mkroom *aroom;
  573. int *dy, *xx, *yy;
  574. {
  575.     coord dd;
  576.  
  577.     if(rn2(2)) {
  578.         *dy = 1;
  579.         finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
  580.     } else {
  581.         *dy = -1;
  582.         finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
  583.     }
  584.     *xx = dd.x;
  585.     *yy = dd.y;
  586.     return(levl[*xx][(*yy)+(*dy)].typ == STONE);
  587. }
  588.  
  589. #ifdef ORACLE
  590. boolean
  591. place_oracle(aroom,dy,xx,yy)
  592. register struct mkroom *aroom;
  593. int *dy, *xx, *yy;
  594. {
  595.     if(!place_niche(aroom,dy,xx,yy)) return FALSE;
  596.  
  597.     dosdoor(*xx,*yy,aroom,DOOR);
  598.     levl[*xx][*yy].doormask = D_NODOOR;
  599.     return TRUE;
  600. }
  601. #endif
  602.  
  603. /* there should be one of these per trap */
  604. const char *engravings[] = {    "", "", "", "", "", "",
  605.                 "?la? ?as ?er?", "ad ae?ar um",
  606.                 "", "", "", "" ,""
  607.                 , "", "ad ae?ar um"
  608. #ifdef SPELLS
  609.                 ,""
  610. #endif
  611.                 ,""
  612. #ifdef POLYSELF
  613.                 ,""
  614. #endif
  615.                 ,""
  616.                 };
  617.  
  618. static void
  619. makeniche(trap_type)
  620. int trap_type;
  621. {
  622.     register struct mkroom *aroom;
  623.     register struct rm *rm;
  624.     register int vct = 8;
  625.     int dy, xx, yy;
  626.     register struct trap *ttmp;
  627.  
  628.     if(doorindex < DOORMAX)
  629.       while(vct--) {
  630.         aroom = &rooms[rn2(nroom)];
  631.         if(aroom->rtype != OROOM) continue;    /* not an ordinary room */
  632.         if(aroom->doorct == 1 && rn2(5)) continue;
  633.         if(!place_niche(aroom,&dy,&xx,&yy)) continue;
  634.  
  635.         rm = &levl[xx][yy+dy];
  636.         if(trap_type || !rn2(4)) {
  637.  
  638.         rm->typ = SCORR;
  639.         rm->scrsym = ' ';        /* _not_ STONE_SYM */
  640.         if(trap_type) {
  641.             ttmp = maketrap(xx, yy+dy, trap_type);
  642.             ttmp->once = 1;
  643.             if (strlen(engravings[trap_type]) > 0)
  644.             make_engr_at(xx, yy-dy, engravings[trap_type]);
  645.         }
  646.         dosdoor(xx, yy, aroom, SDOOR);
  647.         } else {
  648.         rm->typ = CORR;
  649.         rm->scrsym = CORR_SYM;
  650.         if(rn2(7))
  651.             dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
  652.         else {
  653.             (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
  654.             if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE);
  655.         }
  656.         }
  657.         return;
  658.     }
  659. }
  660.  
  661. static void
  662. make_niches()
  663. {
  664.     register int ct = rnd((nroom>>1) + 1);
  665.     boolean    ltptr = TRUE,
  666.         vamp = TRUE;
  667.  
  668.     while(ct--) {
  669.  
  670.         if(dlevel > 15 && !rn2(6) && ltptr) {
  671.  
  672.             ltptr = FALSE;
  673.             makeniche(LEVEL_TELEP);
  674.         } else if (dlevel > 5 && dlevel < 25
  675.                && !rn2(6) && vamp) {
  676.  
  677.             vamp = FALSE;
  678.             makeniche(TRAPDOOR);
  679.         } else    makeniche(NO_TRAP);
  680.     }
  681. }
  682.  
  683. static void
  684. makebigroom()
  685. {
  686.     register int x,y,n;
  687.     register struct mkroom *croom;
  688.     register struct monst *tmonst;
  689.  
  690.     /* make biggest possible room; make sure it's lit */
  691.     (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE);
  692.     croom = &rooms[0];
  693.  
  694.     /* add extra monsters and goodies */
  695.     n = 10 + rn2(15);
  696.     while (n--) {
  697.         x = somex(croom);
  698.         y = somey(croom);
  699.         tmonst = makemon((struct permonst *) 0,x,y);
  700.         if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER])
  701.             (void) maketrap(x,y,WEB);
  702.         if (tmonst && rn2(2))
  703.             tmonst->msleep = 1;
  704.     }
  705.     n = 6 + rn2(10);
  706.     while (n--)
  707.         (void) mkobj_at(0,somex(croom),somey(croom),TRUE);
  708. }
  709.  
  710. static void
  711. makevtele()
  712. {
  713.     makeniche(TELEP_TRAP);
  714. }
  715.  
  716. #define rntwixt(L1,L2)    rn1((L2)-(L1),L1)
  717.  
  718. static void
  719. init_levels()
  720. {
  721. #if defined(STRONGHOLD) && defined(MUSIC)
  722.     register int x;
  723. #endif
  724.  
  725. #ifdef LINT    /* handle constant in conditional context */
  726.     medusa_level = 0;
  727. #else
  728.     medusa_level = rn1(3, HELLLEVEL - 5);
  729. #endif /* LINT */
  730. #ifdef STRONGHOLD
  731.     stronghold_level = rn1(5, medusa_level)+1;
  732. # ifdef MUSIC
  733.     for (x=0; x<5; x++)
  734.         tune[x] = 'A' + rn2(7);
  735.     tune[5] = 0;
  736. # endif
  737.     /* The tower will be on 3 levels */
  738.     tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1;
  739.     /* We don't want the wizard in Vlad's tower */
  740.     do
  741.         wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1;
  742.     while (wiz_level >= tower_level && wiz_level <= tower_level + 2);
  743. #else
  744.     wiz_level     = rntwixt(medusa_level, MAXLEVEL)+1;
  745. #endif /* STRONGHOLD /**/
  746. #ifdef WIZARD
  747.     if (!rn2(15) || wizard)
  748. #else
  749.     if (!rn2(15))
  750. #endif
  751.         /* between the middle of the dungeon and the medusa level */
  752.         bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level);
  753. #ifdef REINCARNATION
  754. # ifdef WIZARD
  755.     if (!rn2(3) || wizard)
  756. # else
  757.     if (!rn2(3))
  758. # endif
  759.         rogue_level = rn1(5,10);
  760. #endif
  761. #ifdef ORACLE
  762.     oracle_level = rn1(4,5);
  763. #endif
  764. }
  765.  
  766. #undef rntwixt
  767.  
  768. static void
  769. makelevel() {
  770.     register struct mkroom *croom, *troom;
  771.     register unsigned int tryct;
  772.     register int x,y;
  773.     struct monst *tmonst;    /* always put a web with a spider */
  774.  
  775.     nroom = 0;
  776.     doorindex = 0;
  777.     rooms[0].hx = -1;    /* in case we are in a maze */
  778.  
  779.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
  780.         levl[x][y] = zerorm;
  781.         level.objects[x][y] = (struct obj *)0;
  782.         level.monsters[x][y] = (struct monst *)0;
  783.     }
  784.  
  785.     oinit();    /* assign level dependent obj probabilities */
  786.     fountsound = 0;
  787.     sinksound = 0;
  788.  
  789.     if (wiz_level == 0)
  790.         init_levels();
  791.     if (
  792. #ifndef STRONGHOLD
  793.         Inhell
  794. #else
  795.         dlevel >= stronghold_level || dlevel < 0
  796. #endif
  797.         || (dlevel > medusa_level && rn2(5))
  798.        ) {
  799.         makemaz();
  800.         return;
  801.     }
  802.  
  803.     /* construct the rooms */
  804.     nroom = 0;
  805.     secret = FALSE;
  806.  
  807. #ifdef REINCARNATION
  808.     if (dlevel == rogue_level) {
  809.         makeroguerooms();
  810.         makerogueghost();
  811.     } else
  812. #endif
  813.     if (dlevel == bigroom_level)
  814.         makebigroom();
  815.     else
  816.         (void) makerooms();
  817.  
  818.     /* construct stairs (up and down in different rooms if possible) */
  819.     croom = &rooms[rn2(nroom)];
  820.     xdnstair = somex(croom);
  821.     ydnstair = somey(croom);
  822.     levl[xdnstair][ydnstair].scrsym = DN_SYM;
  823.     levl[xdnstair][ydnstair].typ = STAIRS;
  824. #ifdef MEDUSA
  825.     if (dlevel == medusa_level) {
  826.         struct monst *mtmp;
  827.         struct obj *otmp;
  828.  
  829.         if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair))
  830.             mtmp->msleep = 1;
  831.         for (tryct = rn1(1,3); tryct; tryct--) {
  832.             x = somex(croom); y = somey(croom);
  833.             if (goodpos(x,y,(struct permonst *)0)) {
  834.                 otmp = mk_tt_object(STATUE, x, y);
  835.                 while(otmp &&
  836.                       resists_ston(&mons[otmp->corpsenm])) {
  837.                     otmp->corpsenm = rndmonnum();
  838.                     otmp->owt = weight(otmp);
  839.                 }
  840.             }
  841.         }
  842.     }
  843. #endif
  844.     if(nroom > 1) {
  845.         troom = croom;
  846.         croom = &rooms[rn2(nroom-1)];
  847.         if(croom >= troom) croom++;
  848.     }
  849.     do {
  850.         xupstair = somex(croom);
  851.         yupstair = somey(croom);
  852.     } while(occupied(xupstair, yupstair));
  853.     levl[xupstair][yupstair].scrsym = UP_SYM;
  854.     levl[xupstair][yupstair].typ = STAIRS;
  855. #ifdef STRONGHOLD
  856.     xdnladder = ydnladder = xupladder = yupladder = 0;
  857. #endif
  858.     is_maze_lev = FALSE;
  859.  
  860. #if defined(SYSV) || defined(DGUX)
  861.     qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp);
  862. #else
  863.     qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp);
  864. #endif
  865. #ifdef REINCARNATION
  866.     if (dlevel == rogue_level) {
  867.        You("feel as though you were here in a previous lifetime.");
  868.        goto skip0;
  869.     }
  870. #endif
  871.     makecorridors();
  872.     make_niches();
  873.  
  874.     /* make a secret treasure vault, not connected to the rest */
  875.     if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) {
  876.  
  877.         troom = &rooms[nroom];
  878.         secret = TRUE;
  879.         if(makerooms()) {
  880.             troom->rtype = VAULT;        /* treasure vault */
  881.             for(x = troom->lx; x <= troom->hx; x++)
  882.             for(y = troom->ly; y <= troom->hy; y++)
  883.                 mkgold((long)(rnd(dlevel*100) + 50), x, y);
  884.             if(!rn2(3))
  885.                 makevtele();
  886.         }
  887.     }
  888.  
  889. #ifdef WIZARD
  890.     if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
  891. #endif
  892. #ifdef ORACLE
  893.     if(dlevel == oracle_level) mkroom(DELPHI);
  894.     /*  It is possible that we find no good place to set up Delphi.
  895.      *  It is also possible to get more than one Delphi using bones levels.
  896.      *  The first is not a problem; the second is a minor nuisance.
  897.      */
  898.     else
  899. #endif
  900.     if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE);
  901.     else
  902. #ifdef THRONES
  903.     if(dlevel > 4 && !rn2(6)) mkroom(COURT);
  904.     else
  905. #endif
  906.     if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
  907.     else
  908. #ifdef ALTARS
  909.     if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE);
  910.     else
  911. #endif
  912.     if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD))
  913.         mkroom(BEEHIVE);
  914.     else
  915.     if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
  916.     else
  917. #ifdef ARMY
  918.     if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD))
  919.         mkroom(BARRACKS);
  920.     else
  921. #endif
  922.     if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
  923.  
  924. #ifdef REINCARNATION
  925. skip0:
  926. #endif
  927.     /* for each room: put things inside */
  928.     for(croom = rooms; croom->hx > 0; croom++) {
  929.         register boolean boxinlev = FALSE;
  930.  
  931.         if(croom->rtype != OROOM) continue;
  932.  
  933.         /* put a sleeping monster inside */
  934.         /* Note: monster may be on the stairs. This cannot be
  935.            avoided: maybe the player fell through a trap door
  936.            while a monster was on the stairs. Conclusion:
  937.            we have to check for monsters on the stairs anyway. */
  938.  
  939.         if(u.uhave_amulet || !rn2(3)) {
  940.             x = somex(croom); y = somey(croom);
  941.             tmonst = makemon((struct permonst *) 0, x,y);
  942.             if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER])
  943.             (void) maketrap (x,y,WEB);
  944.         }
  945.         /* put traps and mimics inside */
  946.         goldseen = FALSE;
  947.         while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
  948.         if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
  949. #ifdef REINCARNATION
  950.         if (dlevel == rogue_level) goto skip_nonrogue;
  951. #endif
  952. #ifdef FOUNTAINS
  953.         if(!rn2(10)) mkfount(0,croom);
  954. #endif
  955. #ifdef SINKS
  956.         if(!rn2(60)) mksink(croom);
  957. #endif
  958. #ifdef ALTARS
  959.         if(!rn2(60)) mkaltar(croom);
  960. #endif
  961.         /* put statues inside */
  962. #ifdef MEDUSA
  963.         if(!rn2(dlevel == medusa_level ? 1 : 20)) {
  964.             struct obj *otmp;
  965.  
  966.             if (!rn2(dlevel == medusa_level ? 2 : 50))
  967.                 otmp = mk_tt_object(STATUE,
  968.                         somex(croom), somey(croom));
  969.             else {
  970.                 otmp = mkcorpstat(STATUE, (struct permonst *)0,
  971.                         somex(croom), somey(croom));
  972.             }
  973.             if (dlevel == medusa_level && otmp) {
  974.                 /* Medusa statues don't contain books */
  975.                 otmp->spe = 0;
  976.                 while(resists_ston(&mons[otmp->corpsenm])) {
  977.                     otmp->corpsenm = rndmonnum();
  978.                     otmp->owt = weight(otmp);
  979.                 }
  980.             }
  981.         }
  982. #else
  983.         if(!rn2(20))
  984.                 (void) mkcorpstat(STATUE, (struct permonst *)0,
  985.                         somex(croom), somey(croom));
  986. #endif
  987.  
  988.         /* put box/chest inside */
  989.         if(!rn2(20) && !boxinlev) {
  990.  
  991.             boxinlev = TRUE;
  992.             (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
  993.                      somex(croom), somey(croom));
  994.         }
  995.  
  996. #ifdef REINCARNATION
  997.     skip_nonrogue:
  998. #endif
  999.         if(!rn2(3)) {
  1000.             (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
  1001.             tryct = 0;
  1002.             while(!rn2(5)) {
  1003.                 if(++tryct > 100){
  1004.                     Printf("tryct overflow4\n");
  1005.                     break;
  1006.                 }
  1007.                 (void) mkobj_at(0, somex(croom), somey(croom),
  1008.                                     TRUE);
  1009.             }
  1010.         }
  1011.     }
  1012. }
  1013.  
  1014. void
  1015. mklev()
  1016. {
  1017.     if(getbones()) return;
  1018.  
  1019.     in_mklev = TRUE;
  1020.     makelevel();
  1021.     bound_digging();
  1022.     in_mklev = FALSE;
  1023. }
  1024.  
  1025. static boolean
  1026. bydoor(x, y)
  1027. register xchar x, y;
  1028. {
  1029.     register boolean tmp1, tmp2;
  1030.  
  1031.     /* break up large expression to help some compilers */
  1032.     tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
  1033.         IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
  1034.     tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
  1035.         IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
  1036.     return(tmp1 || tmp2);
  1037. }
  1038.  
  1039. /* see whether it is allowable to create a door at [x,y] */
  1040. int
  1041. okdoor(x,y)
  1042. register xchar x, y;
  1043. {
  1044.     register boolean near_door = bydoor(x, y);
  1045.  
  1046.     return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
  1047.                doorindex < DOORMAX && !near_door);
  1048. }
  1049.  
  1050. void
  1051. dodoor(x,y,aroom)
  1052. register int x, y;
  1053. register struct mkroom *aroom;
  1054. {
  1055.     if(doorindex >= DOORMAX) {
  1056.         impossible("DOORMAX exceeded?");
  1057.         return;
  1058.     }
  1059.     if(!okdoor(x,y) && nxcor)
  1060.         return;
  1061.     dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
  1062. }
  1063.  
  1064. static boolean
  1065. occupied(x, y)
  1066. register xchar x, y;
  1067. {
  1068.     return(t_at(x, y) || levl[x][y].typ == STAIRS
  1069. #ifdef FOUNTAINS
  1070.         || IS_FOUNTAIN(levl[x][y].typ)
  1071. #endif
  1072. #ifdef THRONES
  1073.         || IS_THRONE(levl[x][y].typ)
  1074. #endif
  1075. #ifdef SINKS
  1076.         || IS_SINK(levl[x][y].typ)
  1077. #endif
  1078. #ifdef ALTARS
  1079.         || levl[x][y].typ == ALTAR
  1080. #endif
  1081.         || is_pool(x,y)
  1082.         );
  1083. }
  1084.  
  1085. /* make a trap somewhere (in croom if mazeflag = 0) */
  1086. void
  1087. mktrap(num, mazeflag, croom)
  1088. register int num, mazeflag;
  1089. register struct mkroom *croom;
  1090. {
  1091.     register struct trap *ttmp;
  1092.     register int kind,nomonst,nomimic,nospider,
  1093. #ifdef POLYSELF
  1094.             nopoly,
  1095. #endif
  1096.             nospikes, nolevltp,
  1097.             nolandmine,
  1098.             tryct = 0;
  1099.  
  1100.     xchar mx,my;
  1101.  
  1102. #ifdef __GNULINT__
  1103.     kind = nomimic = 0;
  1104. #endif
  1105.     if(!num || num >= TRAPNUM) {
  1106.         nomonst = (dlevel < 4) ? 1 : 0;
  1107.         nolevltp = (dlevel < 5) ? 1 : 0;
  1108.         nospikes = (dlevel < 6) ? 1 : 0;
  1109.         nospider = (dlevel < 7) ? 1 : 0;
  1110. #ifdef POLYSELF
  1111.         nopoly = (dlevel < 6) ? 1 : 0;
  1112. #endif
  1113.         nolandmine = (dlevel < 5) ? 1 : 0;
  1114.         nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
  1115.         if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&
  1116.            (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&
  1117.            (mons[PM_GIANT_MIMIC].geno & G_GENOD))
  1118.             nomimic = 1;
  1119.         if(mons[PM_GIANT_SPIDER].geno & G_GENOD)
  1120.             nospider = 1;
  1121.  
  1122.         do {
  1123. #ifdef REINCARNATION
  1124.             if (dlevel==rogue_level) {
  1125.             switch(rn2(7)) {
  1126.                  case 0: kind = BEAR_TRAP; break;
  1127.                  case 1: kind = ARROW_TRAP; break;
  1128.                  case 2: kind = DART_TRAP; break;
  1129.                  case 3: kind = TRAPDOOR; break;
  1130.                  case 4: kind = PIT; break;
  1131.                  case 5: kind = SLP_GAS_TRAP; break;
  1132.                  case 6: kind = RUST_TRAP; break;
  1133.             }
  1134.             } else
  1135. #endif
  1136.                 kind = rnd(TRAPNUM-1);
  1137.             if((kind == MONST_TRAP && (nomonst && nomimic))
  1138.             || ((kind == WEB) && nospider)
  1139.             || (kind == SPIKED_PIT && nospikes)
  1140.             || (kind == LEVEL_TELEP && nolevltp)
  1141. #ifdef POLYSELF
  1142.             || (kind == POLY_TRAP && nopoly)
  1143. #endif
  1144.             || (kind == LANDMINE && nolandmine)
  1145.             )  kind = NO_TRAP;
  1146.         } while(kind == NO_TRAP);
  1147.     } else kind = num;
  1148.  
  1149.     if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) {
  1150.         register struct monst *mtmp;
  1151.  
  1152.         do {
  1153.             if(++tryct > 200) return;
  1154.             /* note: fakedoor maybe on actual door */
  1155.             if(rn2(2)){
  1156.                 if(rn2(2))    mx = croom->hx+1;
  1157.                 else    mx = croom->lx-1;
  1158.                 my = somey(croom);
  1159.             } else {
  1160.                 if(rn2(2))    my = croom->hy+1;
  1161.                 else    my = croom->ly-1;
  1162.                 mx = somex(croom);
  1163.             }
  1164.         } while
  1165.             (MON_AT(mx, my));
  1166.  
  1167.         if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) {
  1168.             mtmp->mimic = 1;
  1169.             mtmp->m_ap_type = M_AP_FURNITURE;
  1170.             mtmp->mappearance = S_cdoor;
  1171.         }
  1172.         return;
  1173.     }
  1174.  
  1175.     do {
  1176.         if(++tryct > 200)
  1177.             return;
  1178.         if(mazeflag){
  1179.             coord mm;
  1180.             mazexy(&mm);
  1181.             mx = mm.x;
  1182.             my = mm.y;
  1183.         } else {
  1184.             mx = somex(croom);
  1185.             my = somey(croom);
  1186.         }
  1187.     } while(occupied(mx, my));
  1188.  
  1189.     ttmp = maketrap(mx, my, kind);
  1190.     if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my);
  1191.     if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP)
  1192.         ttmp->tseen = 1;
  1193. }
  1194.  
  1195. #ifdef FOUNTAINS
  1196. void
  1197. mkfount(mazeflag,croom)
  1198. register struct mkroom *croom;
  1199. register int mazeflag;
  1200. {
  1201.     register xchar mx,my;
  1202.     register int tryct = 0;
  1203.  
  1204.     do {
  1205.         if(++tryct > 200) return;
  1206.         if(mazeflag) {
  1207.          coord mm;
  1208.          mazexy(&mm);
  1209.          mx = mm.x;
  1210.          my = mm.y;
  1211.         } else {
  1212.          mx = somex(croom);
  1213.          my = somey(croom);
  1214.         }
  1215.     } while(occupied(mx, my) || bydoor(mx, my));
  1216.  
  1217.     /* Put a fountain at mx, my */
  1218.     levl[mx][my].typ = FOUNTAIN;
  1219.     levl[mx][my].scrsym = FOUNTAIN_SYM;
  1220.  
  1221.     fountsound++;
  1222. }
  1223. #endif /* FOUNTAINS /**/
  1224.  
  1225. #ifdef SINKS
  1226. static void
  1227. mksink(croom)
  1228. register struct mkroom *croom;
  1229. {
  1230.     register xchar mx,my;
  1231.     register int tryct = 0;
  1232.  
  1233.     do {
  1234.         if(++tryct > 200) return;
  1235.         mx = somex(croom);
  1236.         my = somey(croom);
  1237.     } while(occupied(mx, my) || bydoor(mx, my));
  1238.  
  1239.     /* Put a sink at mx, my */
  1240.     levl[mx][my].typ = SINK;
  1241.     levl[mx][my].scrsym = SINK_SYM;
  1242.  
  1243.     sinksound++;
  1244. }
  1245. #endif /* SINKS /**/
  1246.  
  1247.  
  1248. #ifdef ALTARS
  1249. static void
  1250. mkaltar(croom)
  1251. register struct mkroom *croom;
  1252. {
  1253.     register xchar mx,my;
  1254.     register int tryct = 0;
  1255.  
  1256.     if(croom->rtype != OROOM) return;
  1257.  
  1258.     do {
  1259.         if(++tryct > 200) return;
  1260.         mx = somex(croom);
  1261.         my = somey(croom);
  1262.     } while(occupied(mx, my) || bydoor(mx, my));
  1263.  
  1264.     /* Put an altar at mx, my */
  1265.     levl[mx][my].typ = ALTAR;
  1266.     levl[mx][my].scrsym = ALTAR_SYM;
  1267.     /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */
  1268.     levl[mx][my].altarmask = rn2((int)A_LAW+1);
  1269. }
  1270. #endif /* ALTARS /**/
  1271.